package com.demo.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * author:暗余
 * 2019年4月9日
 * ServerEndpoint的java类，能够接受客户端发送过来的信息和发送给客户端信息
 */

@Component
@ServerEndpoint("/websocket/{username}")
public class WebSocket {

    private Logger logger = LoggerFactory.getLogger(this.getClass());
    /**
     * 在线人数
     */
    public static int onlineNumber = 0;
    /**
     * 以用户的姓名为key，WebSocket为对象保存起来
     */
    private static Map<String, WebSocket> clients = new ConcurrentHashMap<String, WebSocket>();
    /**
     * 会话
     */
    private Session session;
    /**
     * 用户名称
     */
    private String username;

    /* 注入@Value 的示例：*/
//    private static String port;
//
//    @Value("${server.port}")
//    public void getPort(String port) {
//        WebSocket.port = port;
//    }

    /* 注入@Autowired的示例：*/
//    //此处是解决无法注入的关键
//    private static ApplicationContext applicationContext;
//    //你要注入的service或者dao
//    private RestTemplate restTemplate;
//
//    public static void setApplicationContext(ApplicationContext applicationContext) {
//        WebSocket.applicationContext = applicationContext;
//    }
/**
 * 注意：
 *      1.  在@OnOpen注解下的这个open方法中  直接使用@Value和@Autowired是无法注入的，需要像上面一样注入才能注入配置的port或者下面的restTemplate
 *      2. 被注释的代码只是作为扩展参考，可以无需使用，直接删除即可；
 *      3. 原理介绍： 当前端浏览器连接的时候，使用 ws://...连接，会直接进入@Onpen方法内；
 *      4. 浏览器监听服务器返回的消息，是在@onMessage定义消息内容，通过引入此类，然后调用@OnMessage方法即可发送消息
 */


    /**
     * 建立连接
     *
     * @param session
     */
    @OnOpen
    public void onOpen(@PathParam("username") String username, Session session) {

        logger.info("现在来连接的客户id：" + session.getId() + "用户名：" + username);
        onlineNumber++;
//        System.out.println(port);
//        restTemplate= applicationContext.getBean(RestTemplate.class);
//        System.out.println("--------------");
//        System.out.println("端口号"+port);
//        System.out.println("-------------");
//        HttpHeaders headers = new HttpHeaders();
//        MultiValueMap<String, String> map = new LinkedMultiValueMap<String,String>();      //map里面是请求体的内容
//        map.add("token", "eyJhbGciOiJIUzI1NiJ9.eyJ1aWQiOiJ1aWQiLCJleHAiOjE1NjM3Mzc5Nzd9._NT8EQN9xOlRA1KMflV7vl9ByyBHI7rnG7emV0_CARA");
//        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);
//        ResponseEntity<String> response = restTemplate.postForEntity("http://10.4.7.214:9071/checkToken", request, String.class);       //地址替换为自己的
//        System.out.println(response.getBody());
//        ResponseResult responseResult = JSON.parseObject(response.getBody(), ResponseResult.class);
//        System.out.println(responseResult);
//        System.out.println("------");
//        System.out.println(responseResult.getResult().getUserAccount());
        this.username = username;
        this.session = session;
        clients.put(username, this);
        try {
            sendMessageTo(JSON.toJSONString("连接已成功建立"),username);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        logger.info("服务端发生了错误" + error.getMessage());
    }

    /**
     * 连接关闭
     */
    @OnClose
    public void onClose() {
        clients.remove(username);
        onlineNumber--;
    }


    /**
     * 收到客户端的消息  对单发送
     *
     * @param message 消息
     * @param session 会话
     */
    @OnMessage
    public void onMessage(String message, Session session) {
        try {
            JSONObject jsonObject = JSON.parseObject(message);
            String textMessage = jsonObject.getString("message");
            String tousername = jsonObject.getString("to");
            sendMessageTo(JSON.toJSONString(textMessage), tousername);
        } catch (Exception e) {
            logger.info("发生了错误了");
        }
    }

    public void sendMessageTo(String message, String ToUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            if (item.username.equals(ToUserName)) {
                item.session.getAsyncRemote().sendText(message);
                break;
            }
        }
    }

    public void sendMessageAll(String message, String FromUserName) throws IOException {
        for (WebSocket item : clients.values()) {
            item.session.getAsyncRemote().sendText(message);
        }
    }


}
